import { WhiteList } from '@/setting'

/**
 * 判断某个爬是否属于朋友
 */
export const isFriend = (creep: Creep) => {
    return WhiteList.has(creep.owner.username)
}

/**
 * 判断某个爬是否属于敌人
 */
export const isEnemy = (creep: Creep) => {
    return !isFriend(creep)
}

/**
 * 判断某个爬是否是 npc
 */
export const isNpc = (creep: Creep) => {
    return creep.owner.username === 'Invader'
}

/**
 * 判断一组爬是否全是 npc
 */
export const isAllNpc = (creeps: Creep[]) => {
    return creeps.every((creep) => isNpc(creep))
}

/**
 * 计算爬的某种部件的能力
 */
export const calcBodyEffectiveness = function (
    body: BodyPartDefinition[],
    bodyPartType: BodyPartConstant,
    methodName: string,
    basePower: number,
) {
    let power = 0
    body.forEach((i) => {
        if (!i.hits || i.type != bodyPartType) {
            return
        }
        let iPower = basePower
        // @ts-ignore
        if (i.boost && BOOSTS[bodyPartType][i.boost] && BOOSTS[bodyPartType][i.boost][methodName]) {
            // @ts-ignore
            iPower *= BOOSTS[bodyPartType][i.boost][methodName]
        }
        power += iPower
    })
    return power
}

/**
 * 计算爬受到的实际伤害
 */
export const calcCreepDamage = function (creep: Creep, damage: number) {
    let damageReduce = 0,
        damageEffective = damage

    if (_.any(creep.body, (i) => !!i.boost)) {
        for (let i = 0; i < creep.body.length; i++) {
            if (damageEffective <= 0) {
                break
            }
            const bodyPart = creep.body[i]
            let damageRatio = 1
            if (
                bodyPart.boost &&
                // @ts-ignore
                BOOSTS[bodyPart.type][bodyPart.boost] &&
                // @ts-ignore
                BOOSTS[bodyPart.type][bodyPart.boost].damage
            ) {
                // @ts-ignore
                damageRatio = BOOSTS[bodyPart.type][bodyPart.boost].damage
            }
            const bodyPartHitsEffective = bodyPart.hits / damageRatio
            damageReduce += Math.min(bodyPartHitsEffective, damageEffective) * (1 - damageRatio)
            damageEffective -= Math.min(bodyPartHitsEffective, damageEffective)
        }
    }

    damage -= Math.round(damageReduce)
    return damage
}

/**
 * 爬的各项攻击能力
 */
export interface CreepWarAbility {
    attack: number
    heal: number
    rangeAttack: number
    work: number
}

/**
 * 计算爬的各项攻击能力
 */
export const getCreepWarAbility = (creep: Creep): CreepWarAbility => {
    if (creep._warAbility) return creep._warAbility

    let attack = 0
    let rangeAttack = 0
    let heal = 0
    let work = 0
    for (const part of creep.body) {
        if (!part.hits) continue
        if (part.type === 'attack') {
            attack += part.boost ? BOOSTS[part.type][part.boost].attack * ATTACK_POWER : ATTACK_POWER
        } else if (part.type === 'ranged_attack') {
            rangeAttack += part.boost
                ? BOOSTS[part.type][part.boost].rangedAttack * RANGED_ATTACK_POWER
                : RANGED_ATTACK_POWER
        } else if (part.type === 'heal') {
            heal += part.boost ? BOOSTS[part.type][part.boost].heal * HEAL_POWER : HEAL_POWER
        } else if (part.type === 'work') {
            if (part.boost === 'ZH' || part.boost === 'ZH2O' || part.boost === 'XZH2O') {
                work += BOOSTS[part.type][part.boost].dismantle * DISMANTLE_POWER
            } else {
                work += DISMANTLE_POWER
            }
        }
    }
    return (creep._warAbility = { attack, rangeAttack, heal, work })
}

declare global {
    interface Creep {
        /**
         * 战争能力
         */
        _warAbility: CreepWarAbility
    }
}
